package org.altervista.cp.microkernel.io;

import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.UUID;

public class TemporaryFileGenerator {

	private static final long serialVersionUID = 1L;

	public TemporaryFileGenerator(WorkingDirectory wd) throws IOException {
		_tmpDirPath = wd.getTmpDirectory().getAbsolutePath();
	}

	public TemporaryFile newTemporaryFile() {
		return new TemporaryFile() {
			public InputStream getInputStream() throws IOException {
				InputStream is = new FileInputStream(getTmpFile()) {
					public void close() throws IOException {
						_streamList.set(_streamList.indexOf(this), null);
						super.close();
					}
				};
				_streamList.add(is);
				return is;
			}

			public OutputStream getOutputStream() throws IOException {
				OutputStream os = new FileOutputStream(getTmpFile()) {
					public void close() throws IOException {
						_streamList.set(_streamList.indexOf(this), null);
						super.close();
					}
				};
				_streamList.add(os);
				return os;
			}

			public long length() {
				return _tmpFile.length();
			}

			public void readFrom(InputStream is) throws IOException {
				OutputStream out = null;
				try {
					out = getOutputStream();
					new BufferedIO().copy(is, out);
				} finally {
					if (out != null) {
						out.close();
					}
				}
			}

			public void writeTo(OutputStream out) throws IOException {
				InputStream is = null;
				try {
					is = getInputStream();
					new BufferedIO().copy(is, out);
				} finally {
					if (is != null) {
						is.close();
					}
				}
			}

			public void close() {
				finalize();
			}

			protected void finalize() {
				for (Closeable stream : _streamList) {
					try {
						if (stream != null) {
							stream.close();
						}
					} catch (Exception e) {
					}
				}
				_streamList = null;
				if (_tmpFile != null) {
					_tmpFile.delete();
				}
			}

			private File getTmpFile() throws IOException {
				if (_tmpFile == null) {
					while (!(_tmpFile = new File(_tmpDirPath
							+ UUID.randomUUID() + "_"
							+ System.currentTimeMillis() + ".tmp"))
							.createNewFile())
						;
				}
				return _tmpFile;
			}

			private File _tmpFile;
			private ArrayList<Closeable> _streamList = new ArrayList<Closeable>();

		};
	}

	private String _tmpDirPath;
}
